# -*- coding: iso-8859-1 -*-
__author__="Vincent"
__date__ ="$5 mars 2009 22:09:02$"

from hexacoordinate import HexaCoordinate
from vertex import Vertex
from hexagone import Hexagone

class HexManager():   # to replace ListHexagone, which use dict --> not good for algo
    """
    Manage hex list
    """

    linear = 0
    hexes = ()
    vertexes1 = ()
    vertexes2 = ()
    UMAX = 0
    VMAX = 0

    def __init__(self):
        pass

    def __init__(self, (UMAX,VMAX)):
        """
        1-D liste (U,V) is linearized into  I = U + V*linear
        x = mod(I/linear)
        y = ent(I/linear)
        """
        self.UMAX = UMAX
        self.VMAX = VMAX
        self.linear = int(UMAX)
        self.hexes = (UMAX * VMAX) * [0]   #1-D liste (U,V) is linearized into  U + V*linearize ##workf with neg value, but not checked theoritically
        self.vertexes1 = (UMAX * VMAX) * [0]
        self.vertexes2 = (UMAX * VMAX) * [0]

    def Paint(self, dc, size):
        for hex in self.hexes:
            if hex: hex.Draw(dc, size)
        for vertex in self.vertexes1+self.vertexes2:
            if vertex: vertex.PaintValue(dc)

    def AddHexagone(self, hex):       #for backward compatibiliy
        u,v = hex.uv
        self.hexes[int(u)+self.linear*int(v)] = hex

    def UpdateHexagone(self, hex):    #for backward compatibiliy
        u,v = hex.uv
        self.hexes[int(u)+self.linear*int(v)] = hex

    def setHex(self, hex):       #this one should be use for both previous
        """
        Set an hex in the hex Manager according to hex.uv
        """
        u,v = hex.uv            #reqauired : abs(u)<UMAX/2 ; abs(v)<VMAX/2
        self.hexes[int(u)+self.linear*int(v)] = hex

    def PrintClass(self):
        pass

    def GetHexagone(self, (u,v)):
        return self.hexes[int(u)+self.linear*int(v)]

    def GetVoisins(self,hex):
        return self.getHexNeighbours(self, hex)

    def getHexNeighbours(self, hex):
        """
        Returns neighbour hexes
        """
        neighbour_coord = HexaCoordinate().getHexNeighboursFromUV(hex.uv)
        neighbours = []
        for uv in neighbour_coord:
            u,v = uv
            neighbours.append(self.hexes[int(u)+self.linear*int(v)])
        return neighbours

    def setVertex(self, vertex):  #set it in vertexds1 or vertexes according to hex coordinate
        u, v = vertex.uv
        u0, v0 = HexaCoordinate().getClosestHexFromUV(vertex.uv)
        if u-u0 > 0:   # we have vertex1
            self.vertexes1[int(u0)+self.linear*int(v0)] = vertex
        else :          # we have vertex2
            self.vertexes2[int(u0)+self.linear*int(v0)] = vertex

    def getHexesFromVertex(self, vertex):
        """
        return list_of_neighbour_hexes
        """
        u, v = vertex.uv
        u0, v0 = HexaCoordinate().getClosestHexFromUV(vertex.uv)
        hexes = [self.hexes[int(u0)+self.linear*int(v0)]]
        if u-u0 > 0:   # we have vertex1
            hexes.append(self.hexes[int(u0+1)+self.linear*int(v0)])
            hexes.append(self.hexes[int(u0)+self.linear*int(v0-1)])
        else :      # we have vertex2
            hexes.append(self.hexes[int(u0-1)+self.linear*int(v0)])
            hexes.append(self.hexes[int(u0)+self.linear*int(v0+1)])
        return tuple(hexes)

    def computeVertexValues(self):
        """
        compute vertex proba attribute from surrounding hexes
        """
        Vertex.esperance = 0
        for k in Vertex.esperances: Vertex.esperances[k]=0
        for vertex in self.vertexes1+self.vertexes2:
            if vertex:
                hexes = self.getHexesFromVertex(vertex)
                vertex.esperance = 0
                for k in vertex.esperances: vertex.esperances[k]=0      #reset esperances
                for hex in hexes:
                    if hex:
                        if 2<= hex.valeur <= 12 and not hex.hasthief:
                            vertex.esperance += (6 - abs(hex.valeur - 7))
                            Vertex.esperance += (6 - abs(hex.valeur - 7))
                            vertex.esperances[hex.matiere] += (6 - abs(hex.valeur - 7))
                            Vertex.esperances[hex.matiere] += (6 - abs(hex.valeur - 7))

    def get_closest_vertex_with_xy(self, (x,y), d, hexacoord):
        """
        return vertex, which is closest is closest to (x,y) coordinate (at distance d)
        return None if don't find it
        """
        #print "looking for closest vertex to (%s,%s) at distance %s\n" % (x, y,d)
        uv = hexacoord.getClosestVertexFromXY((x,y), d)
        if uv:
            u,v = uv
            #print "found closest vertex is (%s, %s)\n" % (u,v)
            u0v0 = hexacoord.getClosestHexFromUV(uv)
            if u0v0 :
                u0,v0 = u0v0
                #print "belong to hex (%s, %s)\n" % (u0v0[0],u0v0[1])
                if u-u0 > 0:   # we have vertex1
                    return self.vertexes1[int(u0)+self.linear*int(v0)]
                else :          # we have vertex2
                    return self.vertexes2[int(u0)+self.linear*int(v0)]
        else : return

    def get_closest_vertex_with_uv(self, (u,v)):
        pass


if __name__ == "__main__":
    import board
    b = board.Board()
    manager = HexManager((10,10))
    manager.setHex(Hexagone(b,(1,0)))
    manager.setHex(Hexagone(b,(2,0)))
    manager.setHex(Hexagone(b,(2,1)))
    manager.setHex(Hexagone(b,(1,1)))
    manager.setHex(Hexagone(b,(0,0)))
    manager.setHex(Hexagone(b,(0,-1)))
    manager.setHex(Hexagone(b,(1,-1)))
    hexes = manager.getHexNeighbours(manager.GetHexagone((1,0)))
    for h in hexes:
        print "neighbour hex(%d,%d)\n" % (h.uv[0],h.uv[1])
